﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using BTv2.Model;

namespace BTv2.Controls
{
    public class SensorsController
    {

        private static SensorsController _instance;
        private DatabaseController _dbinstance;
        private ObservableCollection<Sensor> _sensors;
        private ObservableCollection<SensorGroup> _sgroups;
        public Dictionary<string, int> SensorTypes;
        public Dictionary<string, int> SensorMetricUnits;
        public ObservableCollection<Sensor> Sensors
        {
            get
            {
                return _sensors;
            }
        }
        public ObservableCollection<SensorGroup> SensorGroups
        {
            get
            {
                return _sgroups;
            }
        }


        public static SensorsController GetInstance()
        {
            if (_instance == null) _instance = new SensorsController();
            return _instance;
        }

        public SensorsController()
        {
            _dbinstance = DatabaseController.GetInstance();
        }

        public async Task<bool> PreloadMericUnits()
        {
            SensorMetricUnits = new Dictionary<string, int>();
            try
            {
                SensorMetricUnits = await _dbinstance.GetMetricUnits();
               
                return true;
            }
            catch
            {
                return false;
            }
        }

        public async Task<bool> PreloadSensorTypes()
        {
            SensorTypes = new Dictionary<string, int>();
            try
            {
                SensorTypes = await _dbinstance.GetSensorTypes();
                return true;
            }
            catch
            {
                return false;
            }
        }

        public async Task<bool> SaveSensor(Sensor s)
        {
            try
            {
                return await _dbinstance.SaveSensor(s);
            }
            catch
            {
                return false;
            }
        }

        public async Task<bool> AddSensor(Sensor s)
        {
            try
            {
                bool res1 = await _dbinstance.AddSensor(s);
                if (!res1) return res1;
                int id = await _dbinstance.GetLastSensorID();
                s.ID = id;
                return res1;
            }
            catch
            {
                return false;
            }
        }

        public async Task<bool> AddSensorType(string type)
        {
            try
            {
                await _dbinstance.AddSensorType(type);
                int id = await _dbinstance.GetLastSensorTypeID();
                SensorTypes.Add(type, id);
                return true;
            }
            catch
            {
                return false;
            }
        }

        public async Task<bool> AddSensorMetricUnit(string smunit)
        {
            try
            {
                await _dbinstance.AddSensorMetricUnit(smunit);
                int id = await _dbinstance.GetLastMetricUnitID();
                SensorMetricUnits.Add(smunit, id);
                return true;
            }
            catch
            {
                return false;
            }
        }

        public async Task<bool> DeleteSensor(Sensor s)
        {
            try
            {
                await _dbinstance.RemoveSensor(s);
                try
                {
                    foreach (var sg in SensorGroups)
                    {
                        if (sg.Sensors.Any(x => x.ID == s.ID))
                        {
                            Application.Current.Dispatcher.Invoke(() => sg.Sensors.Remove(s));

                        }
                    }
                }
                catch
                {
                    return true;
                }
                return true;
            }
            catch
            {
                return false;
            }
        }



        public async Task<bool> PreloadSensors()
        {
            _sensors = new ObservableCollection<Sensor>();
            try
            {
                _sensors = await _dbinstance.GetSensors();
                for (int i = 0; i < _sensors.Count; i++)
                {
                  await  DatabaseController.GetInstance().GetSensorData(_sensors[i], new DateTime(2013, 4, 1), new DateTime(2013, 4, 15));
                }
                return true;
            }
            catch
            {
                return false;
            }
        }

        public async Task<ObservableCollection<Sensor>> GetFilteredSensorList(SensorGroup sg)
        {
            return new ObservableCollection<Sensor>(_sensors.Except(sg.Sensors));
        }

        public async Task<bool> PreloadSensorGroups()
        {
            try
            {
                _sgroups = await _dbinstance.GetSensorGroups(_sensors);
                return true;
            }
            catch
            {
                return false;
            }
        }

        public async Task<bool> SaveSensorGroup(SensorGroup sg, string name, string description)
        {
            try
            {
                bool result = await _dbinstance.SaveSensorGroup(sg, name, description);
                return result;
            }
            catch
            {
                return false;
            }
        }

        public async Task<bool> DeleteSensorGroup(SensorGroup sg)
        {
            try
            {
                return await _dbinstance.RemoveSensorGroup(sg);
            }
            catch
            {
                return false;
            }
        }

    }
}
